<?php
/**
 * RedCross Application
 *
 * @copyright Copyright (c) 2010, Kristian Stokke Tryggestad, Rune Vikestad, Andreas Flaten Wist, Simen Nicolai Echholt, Ole Henrik Jahren
 */

/**
 * Validator for the time of shifts and events
 * 
 * 	@category  	RedCross
 * 	@package	RedCross_Validate
 */
class RedCross_Validate_Time extends Zend_Validate_Abstract
{
    const ERROR = 'error';
    
    const APPEARANCE_TIME_NOT_SET = 'appearanceTimeNotSet';
    const TO_TIME_NOT_SET = 'toTimeNotSet';
    const FROM_TIME_NOT_SET = 'fromTimeNotSet';
    const TO_TIME_EARLIER_THAN_FROM_TIME = 'toTimeEarlierThanFromTime';
    const APPEARANCE_TIME_LATER_THAN_FROM_TIME = 'appearanceTimeLaterThanFromTime';
    
    const FROM_TIME = 'from_time';
    const TO_TIME = 'to_time';
    const APPEARANCE_TIME = 'apperance_time';
    
    protected $_messageTemplates = array(
        self::ERROR         => 'En feil har oppstått.',
        self::APPEARANCE_TIME_NOT_SET => 'Oppmøte tiden er ikke satt.',
        self::FROM_TIME_NOT_SET => 'Starttiden er ikke satt.',
        self::TO_TIME_NOT_SET => 'Slutttiden er ikke satt.',
        self::TO_TIME_EARLIER_THAN_FROM_TIME => 'Sluttiden er tidligere en starttiden.',
        self::APPEARANCE_TIME_LATER_THAN_FROM_TIME => 'Oppmøtetiden er senere en starttiden.'
    );
    
    private $fieldName;
    private $ajax = false;
    
    public function __construct(array $options = null)
    {
        if ($options != null && ($options['name'] === 'appearance_time')) {
            $this->fieldName = $options['name'];
        }
        
        if ($options != null && ($options['name'] === 'from_time')) {
            $this->fieldName = $options['name'];
        }
        
        if ($options != null && ($options['name'] === 'to_time')) {
            $this->fieldName = $options['name'];
        }
        
        if ($options != null && isset($options['ajax'])) {
            $this->ajax = $options['ajax'];
        }
    }

    private function validateAppearanceTime($value, $context = null)
    {
        if(!isset($context['from_time'])) {
            $this->_error(self::FROM_TIME_NOT_SET);
            return false;
        }
        
        $appearanceHours = substr($value, 0, 2);
        $fromHours = substr($context['from_time'], 0, 2);
        if((int)$appearanceHours > (int)$fromHours) {
            $this->_error(self::APPEARANCE_TIME_LATER_THAN_FROM_TIME);
            return false;
        }

        $appearanceMinutes = substr($value, 3, 2);
        $fromMinutes = substr($context['from_time'], 3, 2);
        if((int)$appearanceMinutes > (int)$fromMinutes && $appearanceHours === $fromHours) {
            $this->_error(self::APPEARANCE_TIME_LATER_THAN_FROM_TIME);
            return false;
        }
        return true;
    }

    private function validateFromTime($value, $context = null)
    {
        if(!isset($context['to_time'])) {
            $this->_error(self::TO_TIME_NOT_SET);
            return false;
        }

        $fromHours = substr($value, 0, 2);
        if($this->ajax) {
            $toHours = substr($context['to_time'], 0, 2);
        } else {
            $toHours = $context['to_time']['hours'];
        }
        
        $fromMinutes = substr($value, 3, 2);
        if($this->ajax) {
            $toMinutes = substr($context['to_time'], 3, 2);
        } else {
            $toMinutes = $context['to_time']['minutes'];
        }

        if((int)$fromHours > (int)$toHours){
            $this->_error(self::TO_TIME_EARLIER_THAN_FROM_TIME);
            return false;
        } elseif((int)$fromMinutes > (int)$toMinutes && $fromHours === $toHours) {
            $this->_error(self::TO_TIME_EARLIER_THAN_FROM_TIME);
            return false;
        } else {
            return true;
        }
    }

    public function validateToTime($value, $context = null)
    {
        if(!isset($context['from_time'])) {
            $this->_error(self::FROM_TIME_NOT_SET);
            return false;
        }

        $toHours = substr($value, 0, 2);
        if($this->ajax) {
            $fromHours = substr($context['from_time'], 0, 2);
        } else {
            $fromHours = $context['from_time']['hours'];
        }

        $toMinutes = substr($value, 3, 2);
        if($this->ajax) {
            $fromMinutes = substr($context['from_time'], 3, 2);
        } else {
            $fromMinutes = $context['from_time']['minutes'];
        }

        if((int)$fromHours > (int)$toHours){
            $this->_error(self::TO_TIME_EARLIER_THAN_FROM_TIME);
            return false;
        } elseif((int)$fromMinutes > (int)$toMinutes && $fromHours === $toHours) {
            $this->_error(self::TO_TIME_EARLIER_THAN_FROM_TIME);
            return false;
        } else {
            return true;
        }
    }

    public function isValid($value, $context = null)
    {
        $value = (string) $value;
        $this->_setValue($value);
        
        if(!is_array($context)) {
            $this->_error(self::ERROR);
            return false;
        }

        if($this->fieldName == 'appearance_time') {
            if (!$this->validateAppearanceTime($value, $context)) {
                return false;
            }
        } elseif ($this->fieldName == 'from_time') {
            if ($context['from_date'] === $context['to_date'] && !$this->validateFromTime($value, $context)) {
                return false;
            }
        } elseif ($this->fieldName == 'to_time') {
            if ($context['from_date'] === $context['to_date'] && !$this->validateToTime($value, $context)) {
                return false;
            }
        } else {
            $this->_error(self::ERROR);
            return false;
        }        
        return true;
    }
}